package com.espirit.eap.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.googlecode.cswish.exception.ApplicationException;


public final class DateUtils {
	private static final long MILLISECOND_MINUTE = 1000 * 60;

	/**
	 * @param year			年
	 * @param month			月1-12 月
	 * @param dayOfMonth	日
	 * @param hourOfDay		时0-24
	 * @param minute		分
	 * @param second		秒
	 * @return
	 */
	public static Date generateDate(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second) {
		Calendar c = Calendar.getInstance();
		c.clear();
		
		month = month - 1;
		c.set(year, month, dayOfMonth, hourOfDay, minute, second);
		return c.getTime();
	}
	
	public static Date generateMonthStart(int year, int month) {
		return generateDate(year, month, 1, 0, 0);
	}
	
	public static Date generateMonthEnd(int year, int month) {
		int maxDaysOfMonth = DateUtils.getMaxDaysOfMonth(year, month);
		return generateDate(year, month, maxDaysOfMonth, 23, 59, 59);
	}
	
	public static long millsecond2Minute(long millsecond) {
		return millsecond/MILLISECOND_MINUTE;
	}
	
	public static long millsecond2Minute(Date time) {
		return millsecond2Minute(time.getTime());
	}

	/**
	 * @param year			年
	 * @param month			月1-12 月
	 * @param dayOfMonth	日
	 * @param hourOfDay		时0-24
	 * @param minute		分
	 * @return
	 */
	public static Date generateDate(int year, int month, int dayOfMonth, int hourOfDay, int minute) {
		return generateDate(year, month, dayOfMonth, hourOfDay, minute, 0);
	}
	
	public static int getMaxDaysOfMonth(int year, int month) {
		Calendar c = Calendar.getInstance();
		c.clear();
		
		month = month - 1;
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, month);
		
		return c.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	public static String format(Date date, String pattern) {
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(date);
	}

	public static Date parseDate(String string, String pattern) {
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		try {
			return format.parse(string);
		} catch (ParseException e) {
			throw new ApplicationException(e.getMessage());
		}
	}
	
	public static boolean sameDay(Date date1, Date date2) {
		Calendar c = Calendar.getInstance();
		c.clear();
		c.setTime(date1);
		int date1Y = c.get(Calendar.YEAR);
		int date1M = c.get(Calendar.MONTH);
		int date1D = c.get(Calendar.DAY_OF_MONTH);

		c.clear();
		c.setTime(date2);
		int date2Y = c.get(Calendar.YEAR);
		int date2M = c.get(Calendar.MONTH);
		int date2D = c.get(Calendar.DAY_OF_MONTH);
		
		return date1Y == date2Y && date1M == date2M && date1D == date2D;
	}
	
	public static Date addMinutes(Date time, int minutes) {
		return add(time, Calendar.MINUTE, minutes);
	}

	public static Date addHours(Date time, int hours) {
		return add(time, Calendar.HOUR_OF_DAY, hours);
	}
	
	public static Date addDays(Date time, int days) {
		return add(time, Calendar.DAY_OF_MONTH, days);
	}
	
	private static Date add(Date time, int field, int value) {
		Calendar c = Calendar.getInstance();
		c.clear();
		c.setTime(time);
		
		int oldValue = c.get(field);
		value += oldValue;
		c.set(field, value);
		return c.getTime();
	}
	
	public static int compareMinute(Date time1, Date time2) {
		return (int) ((time1.getTime() - time2.getTime())/MILLISECOND_MINUTE);
	}

	public static Date generateDayStart(Date time) {
		return setHMS(time, 0, 0,0,0);
	}
	
	public static Date generateDayEnd(Date time) {
		Calendar c = Calendar.getInstance();
		c.clear();
		c.setTime(time);
		
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		c.set(Calendar.MILLISECOND, 999);
		return c.getTime();
	}
	
	public static Date setHMS(Date date, int hourOfDay, int minute, int second, int millisecond) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		return c.getTime();
	}

}
